1 package org.apache.commons.betwixt.digester;
2
3 /*
4 * ====================================================================
5 *
6 * The Apache Software License, Version 1.1
7 *
8 * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
9 * reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in
20 * the documentation and/or other materials provided with the
21 * distribution.
22 *
23 * 3. The end-user documentation included with the redistribution, if
24 * any, must include the following acknowlegement:
25 * "This product includes software developed by the
26 * Apache Software Foundation (http://www.apache.org/)."
27 * Alternately, this acknowlegement may appear in the software itself,
28 * if and wherever such third-party acknowlegements normally appear.
29 *
30 * 4. The names "The Jakarta Project", "Commons", and "Apache Software
31 * Foundation" must not be used to endorse or promote products derived
32 * from this software without prior written permission. For written
33 * permission, please contact apache@apache.org.
34 *
35 * 5. Products derived from this software may not be called "Apache"
36 * nor may "Apache" appear in their names without prior written
37 * permission of the Apache Group.
38 *
39 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This software consists of voluntary contributions made by many
54 * individuals on behalf of the Apache Software Foundation. For more
55 * information on the Apache Software Foundation, please see
56 * <http://www.apache.org/>.
57 *
58 */
59
60 import java.beans.BeanInfo;
61 import java.beans.Introspector;
62 import java.beans.PropertyDescriptor;
63
64 import org.apache.commons.betwixt.ElementDescriptor;
65 import org.apache.commons.betwixt.XMLBeanInfo;
66 import org.apache.commons.betwixt.expression.ConstantExpression;
67
68 import org.apache.commons.logging.Log;
69 import org.apache.commons.logging.LogFactory;
70
71 import org.xml.sax.Attributes;
72 import org.xml.sax.SAXException;
73
74 /***
75 * <p><code>ElementRule</code> the digester Rule for parsing
76 * the <element> elements.</p>
77 *
78 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
79 * @version $Id: ElementRule.java,v 1.2 2002/07/01 18:52:21 rdonkin Exp $
80 */
81 public class ElementRule extends RuleSupport {
82
83 /*** Logger */
84 private static final Log log = LogFactory.getLog( ElementRule.class );
85
86 private ClassLoader classLoader;
87
88 private Class beanClass;
89
90 public ElementRule() {
91 this.classLoader = getClass().getClassLoader();
92 }
93
94 // Rule interface
95 //-------------------------------------------------------------------------
96
97 /***
98 * Process the beginning of this element.
99 *
100 * @param attributes The attribute list of this element
101 */
102 public void begin(Attributes attributes) throws Exception {
103 String name = attributes.getValue( "name" );
104
105 ElementDescriptor descriptor = new ElementDescriptor();
106 descriptor.setQualifiedName( name );
107 descriptor.setLocalName( name );
108 String uri = attributes.getValue( "uri" );
109 if ( uri != null ) {
110 descriptor.setURI( uri );
111 }
112
113 String propertyName = attributes.getValue( "property" );
114 descriptor.setPropertyName( propertyName );
115
116 String propertyType = attributes.getValue( "type" );
117
118 if (log.isTraceEnabled()) {
119 log.trace(
120 "(BEGIN) name=" + name + " uri=" + uri
121 + " property=" + propertyName + " type=" + propertyType);
122 }
123
124 // set the property type using reflection
125 descriptor.setPropertyType(
126 getPropertyType( propertyType, beanClass, propertyName )
127 );
128
129
130 if ( propertyName != null && propertyName.length() > 0 ) {
131 configureDescriptor(descriptor);
132 }
133 else {
134 String value = attributes.getValue( "value" );
135 if ( value != null ) {
136 descriptor.setTextExpression( new ConstantExpression( value ) );
137 }
138 }
139
140 Object top = digester.peek();
141 if ( top instanceof XMLBeanInfo ) {
142 XMLBeanInfo beanInfo = (XMLBeanInfo) top;
143 beanInfo.setElementDescriptor( descriptor );
144 beanClass = beanInfo.getBeanClass();
145 }
146 else if ( top instanceof ElementDescriptor ) {
147 ElementDescriptor parent = (ElementDescriptor) top;
148 parent.addElementDescriptor( descriptor );
149 }
150 else {
151 throw new SAXException( "Invalid use of <element>. It should " +
152 "be nested inside <info> or other <element> nodes" );
153 }
154
155 digester.push(descriptor);
156 }
157
158
159 /***
160 * Process the end of this element.
161 */
162 public void end() throws Exception {
163 Object top = digester.pop();
164 }
165
166
167 // Implementation methods
168 //-------------------------------------------------------------------------
169 protected Class getPropertyType( String propertyClassName,
170 Class beanClass, String propertyName ) {
171 // XXX: should use a ClassLoader to handle
172 // complex class loading situations
173 if ( propertyClassName != null ) {
174 try {
175 Class answer = classLoader.loadClass(propertyClassName);
176 if (answer != null) {
177 if (log.isTraceEnabled()) {
178 log.trace("Used specified type " + answer);
179 }
180 return answer;
181 }
182 }
183 catch (Exception e) {
184 log.warn("Cannot load specified type", e);
185 }
186 }
187
188 PropertyDescriptor descriptor =
189 getPropertyDescriptor( beanClass, propertyName );
190 if ( descriptor != null ) {
191 return descriptor.getPropertyType();
192 }
193
194 if (log.isTraceEnabled()) {
195 log.trace("Cannot find property type.");
196 log.trace(" className=" + propertyClassName + " base=" + beanClass + " name=" + propertyName);
197 }
198 return null;
199 }
200
201 /*** Set the Expression and Updater from a bean property name */
202 protected void configureDescriptor(ElementDescriptor elementDescriptor) {
203 Class beanClass = getBeanClass();
204 if ( beanClass != null ) {
205 String name = elementDescriptor.getPropertyName();
206 PropertyDescriptor descriptor =
207 getPropertyDescriptor( beanClass, name );
208 if ( descriptor != null ) {
209 XMLIntrospectorHelper
210 .configureProperty( elementDescriptor, descriptor );
211 getProcessedPropertyNameSet().add( name );
212 }
213 }
214 }
215
216 /***
217 * Returns the property descriptor for the class and property name.
218 * Note that some caching could be used to improve performance of
219 * this method. Or this method could be added to PropertyUtils.
220 */
221 protected PropertyDescriptor getPropertyDescriptor( Class beanClass,
222 String propertyName ) {
223 if ( beanClass != null && propertyName != null ) {
224 if (log.isTraceEnabled()) {
225 log.trace("Searching for property " + propertyName + " on " + beanClass);
226 }
227 try {
228 BeanInfo beanInfo = Introspector.getBeanInfo( beanClass );
229 PropertyDescriptor[] descriptors =
230 beanInfo.getPropertyDescriptors();
231 if ( descriptors != null ) {
232 for ( int i = 0, size = descriptors.length; i < size; i++ ) {
233 PropertyDescriptor descriptor = descriptors[i];
234 if ( propertyName.equals( descriptor.getName() ) ) {
235 log.trace("Found matching method.");
236 return descriptor;
237 }
238 }
239 }
240 log.trace("No match found.");
241 return null;
242 }
243 catch (Exception e) {
244 log.warn( "Caught introspection exception", e );
245 }
246 }
247 return null;
248 }
249
250 }
This page was automatically generated by Maven